using B.S.XZYData.Api.Wrter.Application.Command.AssemblyWorkOrder;
using B.S.XZYData.Domain.ZSHH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;
using SqlSugar;

namespace B.S.XZYData.Api.Wrter.Application.Handler.AssemblyWorkOrder
{
    /// <summary>
    /// 导出装配工单处理器
    /// </summary>
    public class ExportAssemblyWorkOrderHandler : IRequestHandler<ExportAssemblyWorkOrderCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<Domain.ZSHH.AssemblyWorkOrder> _assemblyWorkOrderRepo;
        private readonly IBaseRepository<AssemblyWorkOrderProductDetail> _productDetailRepo;
        private readonly ILogger<ExportAssemblyWorkOrderHandler> _logger;

        public ExportAssemblyWorkOrderHandler(
            IBaseRepository<Domain.ZSHH.AssemblyWorkOrder> assemblyWorkOrderRepo,
            IBaseRepository<AssemblyWorkOrderProductDetail> productDetailRepo,
            ILogger<ExportAssemblyWorkOrderHandler> logger)
        {
            _assemblyWorkOrderRepo = assemblyWorkOrderRepo;
            _productDetailRepo = productDetailRepo;
            _logger = logger;
        }

        public async Task<ApiResult<byte[]>> Handle(ExportAssemblyWorkOrderCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<byte[]>();
            try
            {
                // 构建查询条件
                var query = _assemblyWorkOrderRepo.GetAll()
                    .Where(x => !x.IsDeleted);

                // 单据编号查询
                if (!string.IsNullOrEmpty(request.DocumentNumber))
                {
                    query = query.Where(x => x.DocumentNumber.Contains(request.DocumentNumber));
                }

                // 工单数范围查询
                if (request.WorkOrderCountStart.HasValue)
                {
                    query = query.Where(x => x.WorkOrderCount >= request.WorkOrderCountStart.Value);
                }
                if (request.WorkOrderCountEnd.HasValue)
                {
                    query = query.Where(x => x.WorkOrderCount <= request.WorkOrderCountEnd.Value);
                }

                // 已结束工单数范围查询
                if (request.FinishedWorkOrderCountStart.HasValue)
                {
                    query = query.Where(x => x.CompletedWorkOrderCount >= request.FinishedWorkOrderCountStart.Value);
                }
                if (request.FinishedWorkOrderCountEnd.HasValue)
                {
                    query = query.Where(x => x.CompletedWorkOrderCount <= request.FinishedWorkOrderCountEnd.Value);
                }

                // 创建时间范围查询
                if (request.CreationTimeStart.HasValue)
                {
                    query = query.Where(x => x.CreatorDate >= request.CreationTimeStart.Value);
                }
                if (request.CreationTimeEnd.HasValue)
                {
                    query = query.Where(x => x.CreatorDate <= request.CreationTimeEnd.Value);
                }

                // 排序处理
                query = ApplySorting(query, request.SortField, request.SortDirection);

                // 获取所有数据
                var assemblyWorkOrderList = await query.ToListAsync();

                if (!assemblyWorkOrderList.Any())
                {
                    res.Msg = "没有找到符合条件的装配工单数据";
                    res.Code = ApiEnum.Fail;
                    return await System.Threading.Tasks.Task.FromResult(res);
                }

                // 导出到Excel
                var excelBytes = await ExportToExcel(assemblyWorkOrderList);

                res.Data = excelBytes;
                res.Code = ApiEnum.Success;
                res.Msg = "导出成功";
                return await System.Threading.Tasks.Task.FromResult(res);
            }
            catch (Exception ex)
            {
                _logger.LogError($"导出装配工单异常：{ex.Message}");
                res.Msg = "导出装配工单异常：" + ex.Message;
                res.Code = ApiEnum.Error;
                return await System.Threading.Tasks.Task.FromResult(res);
            }
        }

        /// <summary>
        /// 应用排序
        /// </summary>
        private ISugarQueryable<Domain.ZSHH.AssemblyWorkOrder> ApplySorting(
            ISugarQueryable<Domain.ZSHH.AssemblyWorkOrder> query,
            string sortField,
            string sortDirection)
        {
            switch (sortField.ToLower())
            {
                case "documentnumber":
                    return sortDirection.ToLower() == "asc"
                        ? query.OrderBy(x => x.DocumentNumber)
                        : query.OrderByDescending(x => x.DocumentNumber);

                case "creatordate":
                    return sortDirection.ToLower() == "asc"
                        ? query.OrderBy(x => x.CreatorDate)
                        : query.OrderByDescending(x => x.CreatorDate);

                default:
                    // 默认按Id倒序
                    return query.OrderByDescending(x => x.Id);
            }
        }

        /// <summary>
        /// 导出到Excel
        /// </summary>
        private async System.Threading.Tasks.Task<byte[]> ExportToExcel(List<Domain.ZSHH.AssemblyWorkOrder> assemblyWorkOrderList)
        {
            using (var workbook = new XSSFWorkbook())
            {
                // 创建装配工单工作表
                var workOrderSheet = workbook.CreateSheet("装配工单");
                CreateWorkOrderSheet(workOrderSheet, assemblyWorkOrderList);

                // 创建产品明细工作表
                var productDetailSheet = workbook.CreateSheet("产品明细");
                await CreateProductDetailSheet(productDetailSheet, assemblyWorkOrderList);

                // 导出到内存流
                using (var ms = new MemoryStream())
                {
                    workbook.Write(ms);
                    return ms.ToArray();
                }
            }
        }

        /// <summary>
        /// 创建装配工单工作表
        /// </summary>
        private void CreateWorkOrderSheet(ISheet sheet, List<Domain.ZSHH.AssemblyWorkOrder> assemblyWorkOrderList)
        {
            // 创建标题行样式
            var headerStyle = CreateHeaderStyle(sheet.Workbook);

            // 创建标题行
            var headerRow = sheet.CreateRow(0);
            var headers = new[] { "单据编号", "工单数", "已结束工单数", "单据进度", "备注", "创建时间", "创建人", "修改时间", "修改人" };

            for (int i = 0; i < headers.Length; i++)
            {
                var cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = headerStyle;
                sheet.SetColumnWidth(i, 15 * 256); // 设置列宽
            }

            // 创建数据行
            for (int rowIndex = 0; rowIndex < assemblyWorkOrderList.Count; rowIndex++)
            {
                var workOrder = assemblyWorkOrderList[rowIndex];
                var dataRow = sheet.CreateRow(rowIndex + 1);

                dataRow.CreateCell(0).SetCellValue(workOrder.DocumentNumber ?? "");
                dataRow.CreateCell(1).SetCellValue(workOrder.WorkOrderCount ?? 0);
                dataRow.CreateCell(2).SetCellValue(workOrder.CompletedWorkOrderCount ?? 0);
                dataRow.CreateCell(3).SetCellValue((workOrder.DocumentProgress ?? 0).ToString("F2"));
                dataRow.CreateCell(4).SetCellValue(workOrder.Remarks ?? "");
                dataRow.CreateCell(5).SetCellValue(workOrder.CreatorDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                dataRow.CreateCell(6).SetCellValue(workOrder.Creator ?? "");
                dataRow.CreateCell(7).SetCellValue(workOrder.UpdatorDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                dataRow.CreateCell(8).SetCellValue(workOrder.Updator ?? "");
            }
        }

        /// <summary>
        /// 创建产品明细工作表
        /// </summary>
        private async System.Threading.Tasks.Task CreateProductDetailSheet(ISheet sheet, List<Domain.ZSHH.AssemblyWorkOrder> assemblyWorkOrderList)
        {
            // 创建标题行样式
            var headerStyle = CreateHeaderStyle(sheet.Workbook);

            // 创建标题行
            var headerRow = sheet.CreateRow(0);
            var headers = new[] { "单据编号", "层级编号", "产品编号", "产品名称", "产品规格", "数量", "完成数" };

            for (int i = 0; i < headers.Length; i++)
            {
                var cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = headerStyle;
                sheet.SetColumnWidth(i, 15 * 256); // 设置列宽
            }

            // 获取所有产品明细数据
            var workOrderIds = assemblyWorkOrderList.Select(x => x.Id).ToList();
            var productDetailList = _productDetailRepo.GetAll()
                .Where(x => !x.IsDeleted && workOrderIds.Contains(x.WorkOrderId))
                .OrderBy(x => x.WorkOrderId)
                .OrderBy(x => x.HierarchyNumber)
                .ToList();

            // 创建数据行
            for (int rowIndex = 0; rowIndex < productDetailList.Count(); rowIndex++)
            {
                var productDetail = productDetailList[rowIndex];
                var workOrder = assemblyWorkOrderList.FirstOrDefault(x => x.Id == productDetail.WorkOrderId);
                var dataRow = sheet.CreateRow(rowIndex + 1);

                dataRow.CreateCell(0).SetCellValue(workOrder?.DocumentNumber ?? "");
                dataRow.CreateCell(1).SetCellValue(productDetail.HierarchyNumber ?? "");
                dataRow.CreateCell(2).SetCellValue(productDetail.ProductNumber ?? "");
                dataRow.CreateCell(3).SetCellValue(productDetail.ProductName ?? "");
                dataRow.CreateCell(4).SetCellValue(productDetail.ProductSpecification ?? "");
                dataRow.CreateCell(5).SetCellValue(productDetail.Quantity);
                dataRow.CreateCell(6).SetCellValue(productDetail.CompletedQuantity ?? 0);
            }
        }

        /// <summary>
        /// 创建标题行样式
        /// </summary>
        private ICellStyle CreateHeaderStyle(IWorkbook workbook)
        {
            var headerStyle = workbook.CreateCellStyle();
            var headerFont = workbook.CreateFont();
            headerFont.IsBold = true;
            headerFont.FontHeightInPoints = 12;
            headerStyle.SetFont(headerFont);
            headerStyle.Alignment = HorizontalAlignment.Center;
            headerStyle.VerticalAlignment = VerticalAlignment.Center;
            headerStyle.BorderTop = BorderStyle.Thin;
            headerStyle.BorderBottom = BorderStyle.Thin;
            headerStyle.BorderLeft = BorderStyle.Thin;
            headerStyle.BorderRight = BorderStyle.Thin;
            return headerStyle;
        }
    }
} 